#pragma once

#include <utility>
#include <stdexcept>

template <typename T>
class SingletonTemplate
{
public:	
	template <typename ...Args>
	static T* Instance(Args&& ...args)
	{
		if (nullptr == m_pInstance)
			m_pInstance = new T(std::forward<Args>(args)...);

		return m_pInstance;
	}

	static T* GetInstance()
	{
		if (nullptr == m_pInstance)
			throw std::logic_error("the instanced is not init, please initialize the instance first");

		return m_pInstance;
	}

	static void DestoryInstance()
	{
		if (nullptr == m_pInstance)
			return;
		delete m_pInstance;
		m_pInstance = nullptr;
	}
private:
	SingletonTemplate(void) = default;
	virtual ~SingletonTemplate(void) = default;
	SingletonTemplate(const SingletonTemplate&) = default;
	SingletonTemplate& operator=(const SingletonTemplate&) = default;
private:
	static T* m_pInstance;
};

template <typename T> T* SingletonTemplate<T>::m_pInstance = nullptr;